package com.hxxy.wyp.petsLover.common.services.base.backend.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hxxy.wyp.petsLover.common.entities.Admin;
import com.hxxy.wyp.petsLover.common.entities.ExceptionConst;
import com.hxxy.wyp.petsLover.common.entities.Role;
import com.hxxy.wyp.petsLover.common.entities.vo.req.AdminAddReq;
import com.hxxy.wyp.petsLover.common.entities.vo.resp.AdminRolePermissionVo;
import com.hxxy.wyp.petsLover.common.entities.vo.resp.AdminVo;
import com.hxxy.wyp.petsLover.common.mapper.AdminMapper;
import com.hxxy.wyp.petsLover.common.entities.vo.req.LoginInfo;
import com.hxxy.wyp.petsLover.common.entities.vo.resp.AuthInfo;
import com.hxxy.wyp.petsLover.common.mapper.RoleMapper;
import com.hxxy.wyp.petsLover.common.services.base.backend.AdminService;
import com.hxxy.wyp.petsLover.exception.AppException;
import com.hxxy.wyp.petsLover.utils.EncryptUtils;
import com.hxxy.wyp.petsLover.utils.MD5Utils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName AdminServiceImpl
 * @Description 管理员相关操作
 * @Author wyp
 * @Date 2022/12/20 13:24
 * @Version 1.0
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    /**
     * string resources
     */
    protected static final ResourceBundle RES = ResourceBundle.getBundle("strings/base/admin");


    @Resource
    private AdminMapper adminMapper;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private AdminService adminService;


    /**
     * 根据用户名加盐
     *
     * @param userName
     * @param password
     */
    public String encryptPassword(String userName, String password) {
        String salted = String.format("%s.%s", password, StringUtils.lowerCase(userName));
        return MD5Utils.md5(salted);
    }

    @Override
    public AuthInfo login(LoginInfo loginInfo) {
        AuthInfo authInfo = new AuthInfo();
        String password = encryptPassword(loginInfo.getUsername(), loginInfo.getPassword());
        LambdaQueryWrapper<Admin> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Admin::getUserName, loginInfo.getUsername()).eq(Admin::getUserPassword, password);
        Admin admin = baseMapper.selectOne(lambdaQueryWrapper);
        if (admin == null) {
            throw new AppException(RES.getString(ExceptionConst.USERNAME_OR_PASSWORD_IS_WRONG));
        }

        StpUtil.login(admin.getId());
        authInfo.setAdmin(admin);
        authInfo.setToken(StpUtil.getTokenValue());
        List<String> adminPermissions = adminService.getAdminPermissions(StpUtil.getLoginIdAsString());
        authInfo.setPermissions(adminPermissions);
        authInfo.setCode("200");
        return authInfo;
    }

    /**
     * 获取用户权限
     *
     * @param loginId
     * @return
     */
    @Override
    public List<String> getAdminPermissions(String loginId) {
        String permissios = adminMapper.queryPermissios(loginId);
        String[] split = permissios.split(",");
        return Arrays.stream(split).collect(Collectors.toList());
//        return new ArrayList<>(split);
    }

    /**
     * 获取用户角色
     */
    @Override
    public List<String> getAdminRole(String loginId) {
        String roles = adminMapper.queryRole(loginId);
        String[] split = roles.split(",");
        return Arrays.stream(split).collect(Collectors.toList());
//        return new ArrayList<>(roles);
    }

    /**
     * 根据用户 id 查询用户信息
     */
    @Override
    public Admin findById(Long userId) {
        LambdaQueryWrapper<Admin> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Admin::getId, userId);
        return baseMapper.selectOne(lambdaQueryWrapper);
    }

    /**
     * 查询所有管理员及其权限角色列表
     *
     * @return
     */
    @Override
    public AdminRolePermissionVo selectAll() {
        List<AdminVo> adminVos = new ArrayList<>();
        AdminRolePermissionVo adminRolePermissionVo = new AdminRolePermissionVo();
        Set<String> roleAll = new HashSet<>();
        Set<String> permissionAll = new HashSet<>();
        LambdaQueryWrapper<Admin> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        List<Admin> admins = adminMapper.selectList(lambdaQueryWrapper);
        admins.forEach(
                (admin) -> {
                    AdminVo adminVo = new AdminVo();
                    adminVo.setId(admin.getId());
                    adminVo.setUserName(admin.getUserName());
                    adminVo.setUserPassword(admin.getUserPassword());
                    adminVo.setSex(admin.getSex());
                    adminVo.setRoles(getAdminRole(admin.getId().toString()));
                    adminVo.setPermissions(getAdminPermissions(admin.getId().toString()));
                    adminVo.setStatus(admin.getStatus());
                    String role = adminMapper.queryRole(admin.getId().toString());
                    String permission = adminMapper.queryPermissios(admin.getId().toString());
                    permissionAll.addAll(Arrays.stream(permission.split(",")).collect(Collectors.toList()));
                    roleAll.addAll(Arrays.stream(role.split(",")).collect(Collectors.toList()));
                    adminVos.add(adminVo);
                }
        );
        adminRolePermissionVo.setAdminVos(adminVos);
        adminRolePermissionVo.setRoles(new ArrayList<>(roleAll));
        adminRolePermissionVo.setPermissions(new ArrayList<>(permissionAll));
        return adminRolePermissionVo;
    }

    /**
     * 新增管理员
     *
     * @param adminAddReq
     * @return
     */
    @Override
    public Integer addAdmin(AdminAddReq adminAddReq) {
        Admin admin = new Admin();
        Role role = new Role();
        String encryptPassword = EncryptUtils.encryptPassword(adminAddReq.getUserName(), adminAddReq.getUserPassword());
        BeanUtils.copyProperties(adminAddReq, admin);
        admin.setUserPassword(encryptPassword);
        String roles = "";
        String permissions = "";
        for (String checkRole : adminAddReq.getCheckedRoles()) {
            roles = roles + checkRole + ",";
        }
        for (String checkedPermission : adminAddReq.getCheckedPermissions()) {
            permissions = permissions + checkedPermission + ",";
        }
        role.setRoleName(roles);
        role.setPermissions(permissions);
        roleMapper.insert(role);
        admin.setRoleId(role.getId());
        return adminMapper.insert(admin);
    }

    //删除管理员
    @Override
    public Integer deleteAdmin(String id) {
        Admin admin = adminMapper.selectById(id);
        int i = adminMapper.deleteById(id);
        int j = roleMapper.deleteById(admin.getRoleId());
        if (i > 0 && j > 0) {
            return 1;
        }
        return 0;
    }

    /**
     * 更新管理员
     *
     * @param adminAddReq
     * @return
     */
    @Override
    public Integer updateAdmin(AdminAddReq adminAddReq) {
        Admin admin = new Admin();
        Admin admin1 = adminMapper.selectById(adminAddReq.getId());
        Role role = new Role();
        BeanUtils.copyProperties(adminAddReq, admin);
        if (adminAddReq.getUserPassword().length()<=13){
            String encryptPassword = EncryptUtils.encryptPassword(adminAddReq.getUserName(), adminAddReq.getUserPassword());
            admin.setUserPassword(encryptPassword);
        }
        int i = adminMapper.updateById(admin);
        String roles = "";
        String permissions = "";
        for (String checkRole : adminAddReq.getRoles()) {
            roles = roles + checkRole + ",";
        }
        for (String checkedPermission : adminAddReq.getPermissions()) {
            permissions = permissions + checkedPermission + ",";
        }
        role.setId(admin1.getRoleId());
        role.setRoleName(roles);
        role.setPermissions(permissions);
        int j = roleMapper.updateById(role);
        return i > 0 && j > 0 ? 1 : 0;
    }
}
